﻿#region using statements

using System;
using System.Collections.Generic;
using XNAGameEngine.Logs;

#endregion

namespace XNAGameEngine.GUI
{
    public class GUILayoutRegistry
    {
        #region local fields

        /// <summary>
        /// the GUIManager this object belongs to
        /// </summary>
        private readonly IManagerGUI _guiManager;

        /// <summary>
        /// maps a string to a specific GUILayout type
        /// </summary>
        private readonly Dictionary<string, Type> _registry;

        #endregion

        #region constructors

        /// <summary>
        /// Create a new ManagerGUIRegistry
        /// </summary>
        /// <param name="guiManager">reference to the ManagerGUI this object belongs to</param>
        public GUILayoutRegistry(IManagerGUI guiManager)
        {
            _guiManager = guiManager;
            _registry = new Dictionary<string, Type>();
            ManagerLogs.Write("GUILayoutRegistry: Created");
        }

        #endregion

        #region local methods

        /// <summary>
        /// <para>Register a GUILayout object and map a string to it.</para>
        /// </summary>
        /// <param name="key">the string to map the GUILayout to</param>
        /// <param name="objectType">the GUILayout type to register</param>
        public void RegisterGUILayout(string key, Type objectType)
        {
            if (!objectType.IsSubclassOf(typeof(GUILayout)))
                throw new SystemException(
                    "Cannot register this type. Type passed in does not inherit GUILayout.");

            if (_registry.ContainsValue(objectType))
                throw new SystemException(
                    "This type of object has already been registered");

            if (_registry.ContainsKey(key))
                throw new SystemException(
                    "The value " + key + " has already been registered");

            _registry.Add(key, objectType);
            ManagerLogs.Write("GUILayoutRegistry: " + key + "registered\n");
        }

        /// <summary>
        /// Creates an instance of the specified GUILayout
        /// </summary>
        /// <param name="newObjectKey">GUILayout object to create</param>
        /// <returns>the GUILayout created</returns>
        public GUILayout CreateObjectInstance(string newObjectKey)
        {
            if (!_registry.ContainsKey(newObjectKey))
                throw new SystemException(
                    "The value " + newObjectKey + " has not been registered");

            object[] paramList = new object[2];
            paramList[0] = (IManagerGUI)_guiManager;
            paramList[1] = newObjectKey;

            return
                (GUILayout)
                _registry[newObjectKey].GetConstructors()[0].Invoke(paramList);
        }

        #endregion
    }
}